﻿/**********************************************************
 ●项目：Smartkernel
 ●公司：智能核心信息技术研发中心
 ●作者：曹艳白
 ●邮箱：caoyanbai@gmail.com
 ●创建：2008-08-10
 ●版本：1.0
**********************************************************/
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace Smartkernel.Extensions
{
    /*--------------------------------------------------------
                        正则表达式符号说明
    ●$：输入文本的结尾，例如th$，表示只能以th结尾。
    ●^：输入文本的开头，例如^my，表示只能以my开头。
    ●*：可以重复0次或多次的前导符，例如ra*t，可以匹配raaaat。
    ●.：除了换行符以外的所有单个字符，例如a.c，可以匹配adc。
    ●+：可以重复1次或多次的前导符，例如ra+t，不可以匹配rt。
    ●?：可以重复0次或1次的前导符，例如ra?t，不可以匹配raat。
    ●\b：字边界，例如th\b，以th结尾的任何字。
    --------------------------------------------------------*/
    /// <summary>
    /// String类的扩展
    /// </summary>
    public static partial class SmartStringExtension
    {
        #region 常见操作
        /// <summary>
        /// 截取左边指定长度的字符
        /// </summary>
        /// <param name="input">待截取的字符串</param>
        /// <param name="length">截取的长度</param>
        /// <returns>截取的结果</returns>
        public static string Left(this string input, int length)
        {
            if (input.Length <= length)
            {
                return input;
            }
            else
            {
                return input.Substring(0, length);
            }
        }
        /// <summary>
        /// 截取右边指定长度的字符
        /// </summary>
        /// <param name="input">待截取的字符串</param>
        /// <param name="length">截取的长度</param>
        /// <returns>截取的结果</returns>
        public static string Right(this string input, int length)
        {
            if (input.Length <= length)
            {
                return input;
            }
            else
            {
                return input.Substring(input.Length - length, length);
            }
        }
        /// <summary>
        /// 计算字符串的长度，一个中文算两个字符
        /// </summary>
        /// <param name="input">需要检查的字符串</param>
        /// <returns>长度</returns>
        public static int GetTrueLength(this string input)
        {
            ASCIIEncoding ae = new ASCIIEncoding();
            byte[] datas = ae.GetBytes(input);
            int result = 0;
            for (int i = 0; i < datas.Length; i++)
            {
                if (datas[i] == 63)
                {
                    result++;
                }
                result++;
            }
            return result;
        }
        /// <summary>
        /// 翻转字符串
        /// </summary>
        /// <param name="input">输入的字符串</param>
        /// <returns>翻转的结果</returns>
        public static string Reverse(this string input)
        {
            char[] chars = input.ToCharArray();
            Array.Reverse(chars);
            return new string(chars);
        }
        /// <summary>
        /// 转换为全角或半角格式
        /// </summary>
        /// <param name="input">待转换的字符串</param>
        /// <param name="smartStringCaseType">字符格式类型</param>
        /// <returns>转换之后的结果</returns>
        public static string ToString(this string input, SmartStringCaseType smartStringCaseType)
        {
            string result = string.Empty;
            switch (smartStringCaseType)
            {
                case SmartStringCaseType.SBC:
                    {
                        // 转全角(SBC case)
                        // 全角空格为12288，半角空格为32
                        // 其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
                        char[] chars = input.ToCharArray();
                        for (int i = 0; i < chars.Length; i++)
                        {
                            if (chars[i] == 32)
                            {
                                chars[i] = (char)12288;
                                continue;
                            }
                            if (chars[i] == 46)
                            {
                                chars[i] = (char)12290;
                                continue;
                            }
                            if (chars[i] < 127)
                            {
                                chars[i] = (char)(chars[i] + 65248);
                            }
                        }
                        result = new string(chars);
                        result = result.Replace(".", "。");
                    }
                    break;
                case SmartStringCaseType.DBC:
                    {
                        // 转半角(DBC case)
                        // 全角空格为12288，半角空格为32
                        // 其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
                        char[] chars = input.ToCharArray();
                        for (int i = 0; i < chars.Length; i++)
                        {
                            if (chars[i] == 12288)
                            {
                                chars[i] = (char)32;
                                continue;
                            }
                            if (chars[i] == 12290)
                            {
                                chars[i] = (char)46;
                                continue;
                            }
                            if (chars[i] > 65280 && chars[i] < 65375)
                            {
                                chars[i] = (char)(chars[i] - 65248);
                            }
                        }
                        result = new string(chars);
                        result = result.Replace("。", ",");
                    }
                    break;
            }
            return result;
        }
        /// <summary>
        /// 去除所有Html标记
        /// </summary>
        /// <param name="input">待处理的文本</param>
        /// <returns>处理的结果</returns>
        public static string CleanHtmlTag(this string input)
        {
            string pattern = @"\<.*?>";
            Regex regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            return regex.Replace(input, string.Empty);
        }
        /// <summary>
        /// 转换为十六进制字符串
        /// </summary>
        /// <param name="input">待转换的字符串</param>
        /// <returns>转换的结果</returns>
        public static string ToHexString(this string input)
        {
           return ToHexString(input, Encoding.Default);
        }
        /// <summary>
        /// 转换为十六进制字符串
        /// </summary>
        /// <param name="input">待转换的字符串</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>转换的结果</returns>
        public static string ToHexString(this string input, Encoding encoding)
        {
            return encoding.GetString(SmartHex.ToHex(encoding.GetBytes(input)));
        }
        /// <summary>
        /// 进行去区分大小写的比较
        /// </summary>
        /// <param name="input">原字符串</param>
        /// <param name="other">待比较的字符串</param>
        /// <returns>比较结果</returns>
        public static bool CompareToIgnoreCase(this string input,string other)
        {
            return string.Compare(input, other, true) == 0;
        }
        /// <summary>
        /// 通过正则表达式查找匹配的字符串
        /// </summary>
        /// <param name="input">待处理的字符串</param>
        /// <param name="pattern">模式</param>
        /// <returns>查找到的结果列表</returns>
        public static List<string> Find(this string input, string pattern)
        {
            Regex regex = new Regex(pattern);
            MatchCollection matchs = regex.Matches(input);
            List<string> list = new List<string>();
            foreach (Match match in matchs)
            {
                list.Add(match.Value);
            }
            return list;
        }
        #endregion
    }
    public static partial class SmartStringExtension
    {
        #region 验证方法
        /// <summary>
        /// 正则表达式验证方法
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <param name="pattern">正则表达式模式</param>
        /// <returns>验证的结果：true＝匹配；false＝不匹配</returns>
        public static bool IsMatch(this string input, string pattern)
        {
            return (new Regex(pattern)).IsMatch(input);
        }
        /// <summary>
        /// 验证是不是数字：25，1.23，-10等都是合法的数字
        /// </summary>
        /// <param name="input">待检查的字符串</param>
        /// <returns>验证的结果：true＝是数字；false＝不是数字</returns>
        public static bool IsDouble(this string input)
        {
            double number;
            return double.TryParse(input, out number);
        }
        /// <summary>
        /// 验证是不是邮箱地址
        /// </summary>
        /// <param name="input">待检查的字符串</param>
        /// <returns>验证的结果：true＝是邮箱地址；false＝不是邮箱地址</returns>
        public static bool IsEmail(this string input)
        {
            string pattern = @"^\w+((-\w+)|(\.\w+))*\@\w+((\.|-)\w+)*\.\w+$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是正整数：大于等于0的整数（0.0，2.0，+32.0也判断为整数）
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是正整数；false＝不是正整数</returns>
        public static bool IsPositive(this string input)
        {
            string pattern1 = @"^[+]?[0-9]+[.]?[0]*$";
            string pattern2 = @"^[+-]?[0]+[.]?[0]*$";
            return IsMatch(input, pattern1) || IsMatch(input, pattern2);
        }
        /// <summary>
        /// 验证是不是整数：可以为正也可以为负（0.0，2.0，+32.0，-123.00000也判断为整数）
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是整数；false＝不是整数</returns>
        public static bool IsInteger(this string input)
        {
            string pattern = @"^[+-]?[0-9]+[.]?[0]*$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是中文字符
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是中文；false＝不是中文</returns>
        public static bool IsChinese(this string input)
        {
            string pattern = @"^[\u4e00-\u9fa5]+$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是字母
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsLetter(this string input)
        {
            string pattern = @"^[A-Za-z]+$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是字母和数字组合
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsLetterNumber(this string input)
        {
            string pattern = @"^[A-Za-z0-9]+$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是纯数字组合
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsNumber(this string input)
        {
            string pattern = @"^[0-9]+$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是手机号码
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsMobilePhone(this string input)
        {
            string pattern = @"^[1]{1}[0-9]{10}$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证长度是不是在指定的范围内
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <param name="start">起始边界</param>
        /// <param name="end">结束边界</param>
        /// <returns>验证的结果：true＝在范围内；false＝不在范围内</returns>
        public static bool IsLengthInScope(this string input, int start, int end)
        {
            string pattern = @"^.{" + start + "," + end + "}$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证长度是不是指定的长度
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <param name="length">指定的长度</param>
        /// <returns>验证的结果：true＝在范围内；false＝不在范围内</returns>
        public static bool IsLength(this string input, int length)
        {
            string pattern = @"^.{" + length + "}$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证小数位数是不是在指定的范围内
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <param name="start">起始边界</param>
        /// <param name="end">结束边界</param>
        /// <returns>验证的结果：true＝在范围内；false＝不在范围内</returns>
        public static bool IsDecimalDigitsInScope(this string input, int start, int end)
        {
            string pattern = @"^[0-9]+(.[0-9]{" + start + "," + end + "})$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证小数位数是不是指定的长度
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <param name="length">指定的长度</param>
        /// <returns>验证的结果：true＝在范围内；false＝不在范围内</returns>
        public static bool IsDecimalDigits(this string input, int length)
        {
            string pattern = @"^[0-9]+(.[0-9]{" + length + "})$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是字符、数字或者下划线
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsLetterNumberUnderline(this string input)
        {
            string pattern = @"^[a-zA-Z0-9_]+$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是Url地址。注意，必须有http等协议开头的前缀，www.caoyanbai.com是不能验证通过的
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsUrl(this string input)
        {
            return Uri.IsWellFormedUriString(input, UriKind.Absolute);
        }
        /// <summary>
        /// 验证是不是日期格式。注意，20080123这样的格式是不能验证的，必须是2008-01-23或2008年01月23
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsDateTime(this string input)
        {
            DateTime result;
            return DateTime.TryParse(input, out result);
        }
        /// <summary>
        /// 验证日期是不是在指定的范围内
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <param name="start">起始边界</param>
        /// <param name="end">结束边界</param>
        /// <returns>验证的结果：true＝在范围内；false＝不在范围内</returns>
        public static bool IsDateTimeInScope(this string input, DateTime start, DateTime end)
        {
            DateTime result;
            if (DateTime.TryParse(input, out result))
            {
                if (result >= start && result <= end)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 验证是不是电话号码，匹配010-1234567、010-12345678、0316-1234567、0316-12345678、1234567、12345678。
        /// 以及所有前面的号码加“-”、“转”、“#”之后加分机号码。
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsPhone(this string input)
        {
            return IsMatch(input, @"^\d{7,8}$") || IsMatch(input, @"^\d{7,8}[-转#]\d{1,6}$") || IsMatch(input, @"^\d{3,4}-\d{7,8}$") || IsMatch(input, @"^\d{3,4}-\d{7,8}[-转#]\d{1,6}$");
        }
        /// <summary>
        /// 验证是不是邮编
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsZipCode(this string input)
        {
            string pattern = @"^\d{6}$";
            return IsMatch(input, pattern);
        }
        /// <summary>
        /// 验证是不是IP地址
        /// </summary>
        /// <param name="input">待验证的字符串</param>
        /// <returns>验证的结果：true＝是；false＝不是</returns>
        public static bool IsIPAddress(this string input)
        {
            string pattern = @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$";
            if (IsMatch(input, pattern))
            {
                IPAddress ipAddress;
                return IPAddress.TryParse(input, out ipAddress);
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 判断输入的字符串是不是Null或者空，空格字符也认为是空
        /// </summary>
        /// <param name="input">带验证的字符串</param>
        /// <returns>验证的结果</returns>
        public static bool IsNullOrEmptyOrBlank(this string input)
        {
            if (input == null)
            {
                return true;
            }
            if (input.Length == 0)
            {
                return true;
            }
            if (input.Trim().Length == 0)
            {
                return true;
            }
            return false;
        }
        #endregion
    }
}
